import { Effect, Reducer } from 'umi';
import isEqual from 'lodash/isEqual';
import memoizeOne from 'memoize-one';
import { MenuDataItem } from '@ant-design/pro-layout';
import { queryCurrentUserMenus } from '@/services/menuApis';
import { menuFormatter,
  formatButtons,
  getFormatterMenuData,
  getBreadcrumbNameMap,
  setButtons,
  setRoutes } from '@/utils/authority';

import { TradeResult } from './connect';

export interface MenuModelState {
  menuData: MenuDataItem[];
  breadcrumbNameMap: {};
}

export interface MenuModelType {
  namespace: 'menu';
  state: MenuModelState;
  effects: {
    getMenuData: Effect;
  };
  reducers: {
    saveMenuData: Reducer<MenuModelState>;
  };
}

const memoizeOneFormatter = memoizeOne(getFormatterMenuData, isEqual);
const memoizeOneGetBreadcrumbNameMap = memoizeOne(getBreadcrumbNameMap, isEqual);

const MenuModel: MenuModelType = {
  namespace: 'menu',
  state: {
    menuData: [],
    breadcrumbNameMap: {},
  },

  effects: {
    *getMenuData({ payload }, { put, call }) {
      const response: TradeResult = yield call(queryCurrentUserMenus, payload);
      const { success } = response;
      if (success) {
        const { result } = response;
        const { viewMenu, viewButton } = result;
        const menuData = menuFormatter(viewMenu);
        console.info('menuData', menuData);
        const formatterMenuData = memoizeOneFormatter(viewMenu, undefined);
        console.info('formatterMenuData', formatterMenuData);
        const breadcrumbNameMap = memoizeOneGetBreadcrumbNameMap(formatterMenuData);
        console.info('breadcrumbNameMap', breadcrumbNameMap);
        // 当前登录用户的拥有的路由集合
        const routes = Object.keys(breadcrumbNameMap);
        const buttons = formatButtons(viewButton);
        console.info(buttons);
        setButtons(buttons);
        setRoutes(routes);
        yield put({
          type: 'saveMenuData',
          payload: { menuData, breadcrumbNameMap },
        });
      }
    },
  },

  reducers: {
    saveMenuData(state, action) {
      console.info('saveMenuData', state);
      return {
        ...state,
        // menuData: action.payload || [],
        ...action.payload,
      };
    },
  },
};

export default MenuModel;